package com.mfp.java.testYou.core.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.mfp.java.testYou.core.AppContext;
import com.mfp.java.testYou.core.UserSession;
import com.mfp.java.testYou.core.utils.UrlUtils;
import com.mfp.java.testYou.db.UnauthorizedException;
import com.mfp.java.testYou.db.model.User;
import com.mfp.java.testYou.ui.UIHelper;
import com.mfp.java.testYou.ui.mvc.UserMenuPage;
import com.mfp.java.testYou.ui.mvc.UsersPage;

public class LoginFilter implements Filter {

	private static final Logger log = Logger.getLogger(LoginFilter.class);

	public static final String USERNAME = "user";
	public static final String PASSWORD = "pass";
	public static final String LOGIN_PARAM = "testYouLogin";
	public static final String LOGOUT_PARAM = "testYouLogout";
	public static final String CHANGE_LANG_PARAM = "changeLang";

	private static final String ADMIN_TARGET = UsersPage.URL;
	private static final String USER_TARGET = UserMenuPage.URL;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		String login = request.getParameter(LOGIN_PARAM);
		String logout = request.getParameter(LOGOUT_PARAM);
		String newLang = request.getParameter(CHANGE_LANG_PARAM);

		if (newLang != null) {
			changeLang(UrlUtils.wrapRequest(request), newLang);
		}

		if (login != null) {
			boolean redirected = login(UrlUtils.wrapRequest(request), UrlUtils.wrapResponse(response));
			if (redirected) {
				return;
			}
		}

		if (logout != null) {
			logout(UrlUtils.wrapRequest(request));
		}

		chain.doFilter(request, response);
	}

	private void logout(HttpServletRequest request) {
		request.getSession().invalidate();
	}

	/**
	 * 
	 * @param request
	 * @param response
	 * @return true if redirected
	 */
	private boolean login(HttpServletRequest request, HttpServletResponse response) {
		String userName = request.getParameter(USERNAME);
		CharSequence pass = request.getParameter(PASSWORD);

		User user = null;
		try {
			user = AppContext.getDAO().getUser(userName, pass);
		} catch (UnauthorizedException e) {
			log.info("Unauthorized access: " + e.getMessage());
		}

		if (user != null) {

			UserSession uSession = new UserSession(user);
			request.getSession().setAttribute(UserSession.ATTRIBUTE_NAME, uSession);

			Object o = request.getSession().getAttribute(UIHelper.SESSION_ATTR_LANG);
			if (o == null) {
				request.getSession().setAttribute(UIHelper.SESSION_ATTR_LANG, user.getLang());
			}

			return doRedirectHome(request, response);
		}
		return false;
	}

	private void changeLang(HttpServletRequest request, String newLang) {
		request.getSession().setAttribute(UIHelper.SESSION_ATTR_LANG, newLang);
	}

	/**
	 * Will redirect user to role specific home page.
	 * 
	 * @param request
	 * @param response
	 * @return true is redirected
	 */
	public static boolean doRedirectHome(HttpServletRequest request, HttpServletResponse response) {

		boolean admin = AppContext.getUserSession(request).isAdmin();

		if (admin) {
			return UrlUtils.redirectToTarget(request, response, ADMIN_TARGET);
		} else {
			return UrlUtils.redirectToTarget(request, response, USER_TARGET);
		}
	}
}
